import matplotlib.pyplot as plt
import numpy as np

# 支持中文
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']
# 支持负数
plt.rcParams['axes.unicode_minus'] = False

def create_coordinate_system(x_range=(-np.pi, np.pi), y_range=(-1.2, 1.2), figsize=(10, 4)):
    """
    创建可自定义范围的三角函数坐标系
    
    参数:
    x_range: x轴范围，默认为(-π, π)
    y_range: y轴范围，默认为(-1.2, 1.2)
    figsize: 图形大小，默认为(10, 4)
    
    返回:
    fig, ax: matplotlib的图形和坐标轴对象
    """
    # 创建图形和坐标轴
    fig, ax = plt.subplots(figsize=figsize)
    
    # 设置坐标轴范围
    ax.set_xlim(x_range[0], x_range[1])
    ax.set_ylim(y_range[0], y_range[1])
    
    # 设置坐标原点到(0,0)
    ax.spines['left'].set_position('center')
    ax.spines['bottom'].set_position('center')
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    
    # 计算π的倍数刻度
    x_min, x_max = x_range
    y_min, y_max = y_range
    
    # 计算x轴刻度间隔（π的倍数）
    pi_multipliers = np.arange(np.floor(x_min/np.pi), np.ceil(x_max/np.pi) + 1)
    x_ticks = pi_multipliers * np.pi
    x_ticklabels = []
    
    for multiplier in pi_multipliers:
        if multiplier == 0:
            x_ticklabels.append(r'$0$')
        elif multiplier == 1:
            x_ticklabels.append(r'$\pi$')
        elif multiplier == -1:
            x_ticklabels.append(r'$-\pi$')
        elif multiplier % 1 == 0:  # 整数倍
            if abs(multiplier) == 1:
                continue  # 已处理
            else:
                x_ticklabels.append(r'${}\pi$'.format(int(multiplier)))
        else:  # 分数倍
            num = multiplier
            den = 1
            # 简化分数表示
            if multiplier % 0.5 == 0:
                num = int(2 * multiplier)
                den = 2
            elif multiplier % (1/3) == 0:
                num = int(3 * multiplier)
                den = 3
            elif multiplier % (1/4) == 0:
                num = int(4 * multiplier)
                den = 4
            elif multiplier % (1/6) == 0:
                num = int(6 * multiplier)
                den = 6
            
            if num == 1:
                x_ticklabels.append(r'$\frac{{\pi}}{{{}}}$'.format(den))
            elif num == -1:
                x_ticklabels.append(r'$-\frac{{\pi}}{{{}}}$'.format(den))
            else:
                x_ticklabels.append(r'$\frac{{{}\pi}}{{{}}}$'.format(num, den))
    
    # 设置x轴刻度
    ax.set_xticks(x_ticks)
    ax.set_xticklabels(x_ticklabels, fontsize=10)
    
    # 设置y轴刻度（根据范围动态计算）
    y_interval = max(0.5, (y_max - y_min) / 5)  # 至少0.5的间隔
    y_ticks = np.arange(np.floor(y_min/y_interval)*y_interval, 
                       np.ceil(y_max/y_interval)*y_interval + y_interval/2, 
                       y_interval)
    ax.set_yticks(y_ticks)
    
    # 调整布局
    plt.tight_layout()
    
    return fig, ax

# 测试函数
if __name__ == "__main__":
    # 示例1: 默认范围
    fig1, ax1 = create_coordinate_system()
    x = np.linspace(-np.pi, np.pi, 100)
    y = np.sin(x)
    ax1.plot(x, y, 'b-', linewidth=2, label='y = sin(x)')
    ax1.legend()
    plt.title("默认范围 (-π, π)")
    plt.show()
    
    # 示例2: 自定义范围 (-2π, 2π)
    fig2, ax2 = create_coordinate_system(x_range=(-2*np.pi, 2*np.pi))
    x2 = np.linspace(-2*np.pi, 2*np.pi, 200)
    y2 = np.sin(x2)
    ax2.plot(x2, y2, 'r-', linewidth=2, label='y = sin(x)')
    ax2.legend()
    plt.title("自定义范围 (-2π, 2π)")
    plt.show()
    
    # 示例3: 自定义y轴范围
    fig3, ax3 = create_coordinate_system(y_range=(-2, 2))
    x3 = np.linspace(-np.pi, np.pi, 100)
    y3 = np.sin(x3)
    ax3.plot(x3, y3, 'g-', linewidth=2, label='y = sin(x)')
    ax3.legend()
    plt.title("自定义y轴范围 (-2, 2)")
    plt.show()
    
    # 示例4: 完全自定义范围
    fig4, ax4 = create_coordinate_system(x_range=(-3*np.pi, 3*np.pi), y_range=(-1.5, 1.5))
    x4 = np.linspace(-3*np.pi, 3*np.pi, 300)
    y4 = np.sin(x4)
    ax4.plot(x4, y4, 'm-', linewidth=2, label='y = sin(x)')
    ax4.legend()
    plt.title("完全自定义范围 (-3π, 3π) 和 (-1.5, 1.5)")
    plt.show()